# 导入我们需要的模块
import torch
import torch.nn.functional as F
import numpy as np

# # 定义神经网络
# class Net(torch.nn.Module):
#     # n_feature 输入的神经元的数目  n_hidden 隐藏层中的神经元数目 n_output输入神经元的数目
#     def __init__(self, n_feature, n_hidden, n_output, ):
#         super(Net, self).__init__()  # 必要步骤 调用父类
#         # 定义我们的隐藏层
#         self.hidden = torch.nn.Linear(n_feature, n_hidden)
#         # 定义我们的输入层
#         self.predict = torch.nn.Linear(n_hidden, n_output)
#
#     def forward(self, x):
#         # 在我们的隐藏层，和输入层之间 加上我们的激活函数
#         x = F.relu(self.hidden(x))
#         x = self.predict(x)
#         return x
#
#
# # 一个输入神经元   10个隐藏神经元 1个输出神经元
# net = Net(1, 10, 1)
# # 打印这个神经网络
# print(net)
#
# net2 = torch.nn.Sequential(
#     torch.nn.Linear(1, 10),
#     torch.nn.ReLU(),
#     torch.nn.Linear(10, 1)
# )
# print(net2)  # 和第一个的结果是一样的
#
# loss_func = torch.nn.MSELoss()
#
# net_SGD = Net()
# torch.optim.SGD(net_SGD.parameters(), lr=0.01)

######创建一个假数据######
n_data = torch.ones(100, 2)
# 第一个数据集
x0 = torch.normal(2 * n_data, 1)
y0 = torch.zeros(100)
# 第二个数据集
x1 = torch.normal(-2 * n_data, 1)
y1 = torch.ones(100)
# 合并数据集  --> 合并 并改变格式
x = torch.cat((x0, x1), 0).type(torch.FloatTensor)  # 32位浮点数
y = torch.cat((y0, y1)).type(torch.LongTensor)  # 64 位整型


######定义我们的神经网络#######
class Net(torch.nn.Module):
    # n_feature 输入的神经元的数目  n_hidden 隐藏层中的神经元数目 n_output输入神经元的数目
    def __init__(self, n_feature, n_hidden, n_output):
        # 必要步骤 调用父类
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)
        self.predict = torch.nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x


######实例化我们的神经网络######
net = Net(2, 10, 2)
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
loss_func = torch.nn.CrossEntropyLoss()  # 使用标签误差
######训练我们的神经网络######
for i in range(100):
    prediction = net(x)
    loss = loss_func(prediction, y)
    # 梯度归零
    optimizer.zero_grad()
    # 计算梯度
    loss.backward()
    # 更新结点
    optimizer.step()
    if i % 20 == 0:
        print(loss)

x1 = torch.FloatTensor([2, 2])  # !!! 必须要转换成Tensor的形式
np.argmax(net(x1).data.numpy)
